<template>
    <div class="map-container">
        <div id="map"></div>

        <!-- 控制面板组件 -->
        <ControlPanel :current-draw-type="currentDrawType" :layer-status="layerStatus" @clear-highlight="clearHighlight"
            @update-layer="updateLayer" @toggle-draw="toggleDraw" @clear-drawings="clearDrawings" @go-home="goHome" />

        <!-- 图例组件 -->
        <MapLegend />

        <!-- 信息面板组件 -->
        <InfoPanel :zoom-level="zoomLevel" :center-coord="centerCoord" :layer-status="layerStatus"
            :click-info="clickInfo" :measure-info="measureInfo" />

        <!-- 弹窗组件 -->
        <div ref="popup" class="ol-popup">
            <a href="#" ref="popupCloser" class="ol-popup-closer"></a>
            <div ref="popupContent" id="popup-content"></div>
        </div>
    </div>
</template>

<script>
import { defineComponent, ref, onMounted, onBeforeUnmount, provide } from 'vue';
import { useRouter } from 'vue-router';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import VectorTileLayer from 'ol/layer/VectorTile';
import VectorLayer from 'ol/layer/Vector';
import XYZ from 'ol/source/XYZ';
import VectorTileSource from 'ol/source/VectorTile';
import VectorSource from 'ol/source/Vector';
import MVT from 'ol/format/MVT';
import Overlay from 'ol/Overlay';
import { fromLonLat, toLonLat } from 'ol/proj';
import { Circle, Fill, Stroke, Style } from 'ol/style';
import { Draw } from 'ol/interaction';
import { getLength, getArea } from 'ol/sphere';
import { unByKey } from 'ol/Observable';

// 导入子组件
import ControlPanel from './ControlPanel.vue';
import MapLegend from './MapLegend.vue';
import InfoPanel from './InfoPanel.vue';

export default defineComponent({
    name: 'PbfOpenLayer',
    components: {
        ControlPanel,
        MapLegend,
        InfoPanel
    },
    setup() {
        const router = useRouter();

        // 响应式数据
        const zoomLevel = ref('-');
        const centerCoord = ref('-');
        const layerStatus = ref('未加载');
        const clickInfo = ref('无');
        const measureInfo = ref(''); // 测量信息
        const currentDrawType = ref(null); // 当前绘制类型

        // 引用DOM元素
        const popup = ref(null);
        const popupCloser = ref(null);
        const popupContent = ref(null);

        // 地图相关变量
        let map = null;
        let gaodeLayer = null;
        let pbfLayer = null;
        let highlightLayer = null;
        let drawLayer = null; // 绘图图层
        let popupOverlay = null;
        let selectedFeature = null;
        let drawInteraction = null; // 绘图交互
        let drawListener = null; // 绘图监听器

        // 提供给子组件的地图实例
        provide('mapInstance', {
            getMap: () => map,
            getDrawLayer: () => drawLayer,
            getHighlightLayer: () => highlightLayer,
            getPbfLayer: () => pbfLayer
        });

        // 返回首页
        const goHome = () => {
            router.push('/');
        };

        // 初始化地图
        const initMap = () => {
            // 创建高德地图图层
            gaodeLayer = new TileLayer({
                source: new XYZ({
                    url: 'http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
                    wrapX: true
                }),
                zIndex: 0
            });

            // 创建弹窗覆盖层
            popupOverlay = new Overlay({
                element: popup.value,
                autoPan: true,
                autoPanAnimation: {
                    duration: 250
                }
            });

            // 创建地图
            map = new Map({
                target: 'map',
                layers: [gaodeLayer],
                view: new View({
                    center: fromLonLat([113.2644, 23.1291]), // 广东省广州市附近
                    zoom: 8,
                    minZoom: 4,
                    maxZoom: 18
                }),
                overlays: [popupOverlay]
            });

            // 添加高亮图层
            highlightLayer = new VectorLayer({
                source: new VectorSource(),
                style: createHighlightStyle(),
                zIndex: 100
            });
            map.addLayer(highlightLayer);

            // 添加绘图图层
            drawLayer = new VectorLayer({
                source: new VectorSource(),
                style: createDrawStyle(),
                zIndex: 90
            });
            map.addLayer(drawLayer);

            // 添加PBF图层
            addPbfLayer();

            // 添加点击事件
            map.on('click', function (evt) {
                // 如果正在绘制，则不处理PBF图层点击
                if (currentDrawType.value) return;

                // 清除之前的高亮
                clearHighlight();

                // 查找点击的要素
                const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
                    return feature;
                }, {
                    layerFilter: function (layer) {
                        return layer === pbfLayer;
                    }
                });

                if (feature) {
                    // 高亮选中的图斑并显示信息
                    highlightFeature(feature);
                    showFeatureInfo(feature, evt.coordinate);
                } else {
                    popupOverlay.setPosition(undefined);
                    clickInfo.value = '无';
                }
            });

            // 鼠标悬停效果
            map.on('pointermove', function (evt) {
                // 如果正在绘制，显示绘制提示
                if (currentDrawType.value) {
                    map.getTargetElement().title = '点击地图绘制，双击结束绘制';
                    return;
                }

                const pixel = map.getEventPixel(evt.originalEvent);
                const hit = map.hasFeatureAtPixel(pixel, {
                    layerFilter: function (layer) {
                        return layer === pbfLayer;
                    }
                });
                map.getTargetElement().style.cursor = hit ? 'pointer' : '';
            });

            // 弹窗关闭事件
            popupCloser.value.onclick = function () {
                clearHighlight();
                return false;
            };

            // 监听地图事件
            map.on('moveend', updateInfo);

            updateInfo();
        };

        // 添加PBF图层
        const addPbfLayer = () => {
            // 移除已存在的PBF图层
            if (pbfLayer) {
                map.removeLayer(pbfLayer);
            }

            // 创建PBF矢量瓦片源
            const vectorSource = new VectorTileSource({
                format: new MVT(),
                url: 'http://8.134.103.174:8081/pbf/guandongpbf/{z}/{x}/{y}.pbf',
                maxZoom: 14,
                minZoom: 4,
                wrapX: true
            });

            // 创建PBF矢量瓦片图层
            pbfLayer = new VectorTileLayer({
                source: vectorSource,
                style: createPbfStyle(),
                zIndex: 10
            });

            map.addLayer(pbfLayer);
            layerStatus.value = '已加载';
        };

        // 创建PBF图层样式
        const createPbfStyle = () => {
            return function (feature) {
                const geometryType = feature.getGeometry().getType();

                switch (geometryType) {
                    case 'Point':
                        return new Style({
                            image: new Circle({
                                radius: 5,
                                fill: new Fill({
                                    color: 'rgba(255, 0, 0, 0.7)'
                                }),
                                stroke: new Stroke({
                                    color: '#ffffff',
                                    width: 1
                                })
                            })
                        });
                    case 'LineString':
                    case 'MultiLineString':
                        return new Style({
                            stroke: new Stroke({
                                color: 'rgba(0, 0, 255, 0.7)',
                                width: 2
                            })
                        });
                    case 'Polygon':
                    case 'MultiPolygon':
                        return new Style({
                            stroke: new Stroke({
                                color: '#006600',
                                width: 1
                            }),
                            fill: new Fill({
                                color: 'rgba(0, 200, 0, 0.5)'
                            })
                        });
                    default:
                        return new Style({
                            fill: new Fill({
                                color: 'rgba(0, 0, 255, 0.5)'
                            }),
                            stroke: new Stroke({
                                color: '#0000ff',
                                width: 1
                            })
                        });
                }
            };
        };

        // 创建高亮样式
        const createHighlightStyle = () => {
            return function (feature) {
                const geometryType = feature.getGeometry().getType();

                switch (geometryType) {
                    case 'Point':
                        return new Style({
                            image: new Circle({
                                radius: 8,
                                fill: new Fill({
                                    color: 'rgba(255, 255, 0, 0.8)'
                                }),
                                stroke: new Stroke({
                                    color: '#ff0000',
                                    width: 2
                                })
                            })
                        });
                    case 'LineString':
                    case 'MultiLineString':
                        return new Style({
                            stroke: new Stroke({
                                color: 'rgba(255, 0, 0, 0.8)',
                                width: 4
                            })
                        });
                    case 'Polygon':
                    case 'MultiPolygon':
                        return new Style({
                            stroke: new Stroke({
                                color: '#ff0000',
                                width: 3
                            }),
                            fill: new Fill({
                                color: 'rgba(255, 255, 0, 0.8)'
                            })
                        });
                    default:
                        return new Style({
                            fill: new Fill({
                                color: 'rgba(255, 255, 0, 0.8)'
                            }),
                            stroke: new Stroke({
                                color: '#ff0000',
                                width: 2
                            })
                        });
                }
            };
        };

        // 创建绘图样式
        const createDrawStyle = () => {
            return function (feature) {
                const geometryType = feature.getGeometry().getType();

                switch (geometryType) {
                    case 'Point':
                        return new Style({
                            image: new Circle({
                                radius: 6,
                                fill: new Fill({
                                    color: '#3399CC'
                                }),
                                stroke: new Stroke({
                                    color: '#fff',
                                    width: 2
                                })
                            })
                        });
                    case 'LineString':
                        return new Style({
                            stroke: new Stroke({
                                color: '#3399CC',
                                width: 3
                            })
                        });
                    case 'Polygon':
                        return new Style({
                            stroke: new Stroke({
                                color: '#3399CC',
                                width: 3
                            }),
                            fill: new Fill({
                                color: 'rgba(51, 153, 204, 0.2)'
                            })
                        });
                    default:
                        return new Style({
                            stroke: new Stroke({
                                color: '#3399CC',
                                width: 2
                            }),
                            fill: new Fill({
                                color: 'rgba(51, 153, 204, 0.2)'
                            })
                        });
                }
            };
        };

        // 高亮选中的图斑
        const highlightFeature = (feature) => {
            // 保存当前选中的要素
            selectedFeature = feature;

            // 获取要素的属性
            const properties = feature.getProperties();

            // 创建新的高亮要素（直接引用原几何对象）
            const highlightFeature = feature.clone();

            // 添加到高亮图层
            highlightLayer.getSource().clear(); // 先清除之前的要素
            highlightLayer.getSource().addFeature(highlightFeature);

            // 更新信息面板
            const name = properties.name || properties.adcode || '未知区域';
            clickInfo.value = name;
        };

        // 显示要素信息
        const showFeatureInfo = (feature, coordinate) => {
            const properties = feature.getProperties();
            const geometry = feature.getGeometry();
            const geometryType = geometry.getType();

            // 构建弹窗内容
            let content = '<div class="popup-title">要素属性信息</div>';

            // 显示几何类型
            content += `<div class="popup-attribute"><span class="attr-name">几何类型:</span> ${geometryType}</div>`;

            // 显示属性信息
            for (let key in properties) {
                // 跳过几何属性和内部属性
                if (key !== 'geometry' && !key.startsWith('__') && properties[key] !== null && properties[key] !== undefined) {
                    let value = properties[key];
                    // 格式化复杂对象
                    if (key === 'parent' && typeof value === 'object') {
                        value = JSON.stringify(value);
                    }
                    if (key === 'acroutes' && Array.isArray(value)) {
                        value = value.join(', ');
                    }
                    content += `<div class="popup-attribute"><span class="attr-name">${key}:</span> ${value}</div>`;
                }
            }

            // 显示坐标信息（对于点要素）
            if (geometryType === 'Point') {
                const coords = toLonLat(geometry.getCoordinates());
                content += `<div class="popup-attribute"><span class="attr-name">坐标:</span> ${coords[0].toFixed(6)}, ${coords[1].toFixed(6)}</div>`;
            }

            // 更新弹窗内容并显示
            popupContent.value.innerHTML = content;
            popupOverlay.setPosition(coordinate);
        };

        // 清除高亮
        const clearHighlight = () => {
            // 清除高亮图层中的所有要素
            highlightLayer.getSource().clear();

            // 清除选中状态
            selectedFeature = null;

            // 关闭弹窗
            popupOverlay.setPosition(undefined);

            // 更新信息面板
            clickInfo.value = '无';
        };

        // 切换绘制工具
        const toggleDraw = (type) => {
            // 如果点击的是当前激活的类型，则取消激活
            if (currentDrawType.value === type) {
                deactivateDraw();
                return;
            }

            // 先取消当前的绘制
            deactivateDraw();

            // 设置新的绘制类型
            currentDrawType.value = type;

            // 创建绘制交互
            drawInteraction = new Draw({
                source: drawLayer.getSource(),
                type: type,
                style: createDrawStyle()
            });

            // 添加绘制交互到地图
            map.addInteraction(drawInteraction);

            // 监听绘制事件
            if (type === 'LineString' || type === 'Polygon') {
                drawListener = drawInteraction.on('drawstart', function (evt) {
                    // 清除之前的测量信息
                    measureInfo.value = '';
                });

                drawInteraction.on('drawend', function (evt) {
                    const feature = evt.feature;
                    const geometry = feature.getGeometry();
                    const geometryType = geometry.getType();

                    // 计算并显示测量结果
                    if (geometryType === 'Point') {
                        // 对于点要素，显示坐标信息
                        const coords = toLonLat(geometry.getCoordinates());
                        measureInfo.value = `坐标: ${coords[0].toFixed(6)}, ${coords[1].toFixed(6)}`;
                        alert(`点坐标：${coords[0].toFixed(6)}, ${coords[1].toFixed(6)}`);

                    } else if (geometryType === 'LineString') {
                        const length = getLength(geometry);
                        const kilometers = length / 1000;
                        measureInfo.value = `距离: ${kilometers.toFixed(2)} 公里`;
                        alert(`长度：${measureInfo.value}公里`);
                    } else if (geometryType === 'Polygon') {
                        const area = getArea(geometry);
                        const squareKilometers = area / 1000000;
                        measureInfo.value = `面积: ${squareKilometers.toFixed(2)} 平方公里`;
                        alert(`面积：${measureInfo.value}平方公里`);
                    }
                });

            }

            // 提示用户如何操作
            alert(`已激活${type === 'Point' ? '点绘制' : type === 'LineString' ? '线绘制(测距)' : '面绘制'}模式\n点击地图开始绘制，${type === 'Point' ? '点击一次完成绘制' : '双击结束绘制'
                }`);
        };

        // 取消绘制
        const deactivateDraw = () => {
            if (drawInteraction) {
                map.removeInteraction(drawInteraction);
                drawInteraction = null;
            }
            if (drawListener) {
                unByKey(drawListener);
                drawListener = null;
            }
            currentDrawType.value = null;
            measureInfo.value = '';
        };

        // 清除所有绘制
        const clearDrawings = () => {
            if (drawLayer) {
                drawLayer.getSource().clear();
            }
            deactivateDraw();
            measureInfo.value = '';
        };

        // 更新图层
        const updateLayer = () => {
            try {
                addPbfLayer();
                clearHighlight();
                layerStatus.value = '更新成功';
            } catch (error) {
                layerStatus.value = '更新失败: ' + error.message;
            }
        };

        // 更新信息显示
        const updateInfo = () => {
            if (map) {
                const view = map.getView();
                zoomLevel.value = view.getZoom().toFixed(2);
                const center = toLonLat(view.getCenter());
                centerCoord.value = `${center[0].toFixed(6)}, ${center[1].toFixed(6)}`;
            }
        };

        onMounted(() => {
            initMap();
        });

        onBeforeUnmount(() => {
            if (map) {
                map.setTarget(null);
            }
        });

        return {
            zoomLevel,
            centerCoord,
            layerStatus,
            clickInfo,
            measureInfo,
            currentDrawType,
            popup,
            popupCloser,
            popupContent,
            clearHighlight,
            updateLayer,
            goHome,
            toggleDraw,
            clearDrawings
        };
    }
});
</script>

<style scoped>
.map-container {
    width: 100vw;
    height: 100vh;
    position: fixed;
    overflow: hidden;
    /* 添加以下属性确保定位正确 */
    left: 0;
    top: 0;
}

#map {
    width: 100vw;
    height: 100vh;
}

.ol-popup {
    position: absolute;
    background-color: white;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
    padding: 15px;
    border-radius: 10px;
    border: 1px solid #cccccc;
    bottom: 12px;
    left: -50px;
    min-width: 280px;
    max-height: 300px;
    overflow-y: auto;
}

.ol-popup:after,
.ol-popup:before {
    top: 100%;
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}

.ol-popup:after {
    border-top-color: white;
    border-width: 10px;
    left: 48px;
    margin-left: -10px;
}

.ol-popup:before {
    border-top-color: #cccccc;
    border-width: 11px;
    left: 48px;
    margin-left: -11px;
}

.ol-popup-closer {
    text-decoration: none;
    position: absolute;
    top: 2px;
    right: 8px;
    color: #666;
}

.ol-popup-closer:after {
    content: "✖";
}

.popup-title {
    font-weight: bold;
    margin-bottom: 10px;
    padding-bottom: 5px;
    border-bottom: 1px solid #eee;
}

.popup-attribute {
    margin-bottom: 5px;
}

.popup-attribute .attr-name {
    font-weight: bold;
    display: inline-block;
    width: 120px;
}
</style>